`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    15:34:07 10/27/2011 
// Design Name: 
// Module Name:    SNESControllerTest 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: Testing the input of the SNES controller with the LCD screen
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module SNESControllerTest(CLK, reset, latch,  pulse, data, plyr_input);

// Inputs
input CLK, reset, data;

// Outputs
output latch, pulse;
output [11:0] plyr_input;

// reg's	
reg latch, pulse;

// states
reg [7:0] state, nextstate, currentstate;
reg [23:0] count, temp;
reg B, Y, Start, Select, Up, Down, Left, Right, A, X, L, R;

// Parameters
	parameter LATCH = 1;	// latch
	parameter WAIT = 2;	// wait
	parameter PULSE = 3; // pulse
	parameter READ_A = 12; // A button
	parameter READ_B = 4;	// B button
	parameter READ_X = 13;	// X button
	parameter READ_Y = 5;	// Y button
	parameter READ_L = 14;	// L button
	parameter READ_R = 15;	// R button
	parameter READ_START = 6; // Start button
	parameter READ_SELECT = 7; // Select button
	parameter READ_UP = 8; // Up button
	parameter READ_DOWN = 9; // Down button
	parameter READ_LEFT = 10; // Left button
	parameter READ_RIGHT = 11; // Right button
	parameter READ_NONE = 16; // UNUSED
	parameter WAIT_TO_LATCH = 17; // Wait 16.67 ms before going to next latch
	
	parameter TWELVE_US = 12'h258;    //count for 12 us on a 50 MHz clock
	parameter SIX_US = 12'h12C; 		//count for 6 us on a 50 MHz clock
	parameter SIXTEEN_MS = 24'hcb7dc;	// count for 16.67 ms on a 50 MHz clock

assign plyr_input = {B, Y, Start, Select, Up, Down, Left, Right, A, X, L, R};

// ALWAYS block
always@(posedge CLK) begin
	if(reset) begin
		state <= 0;
		count <= 0;
		temp <= 0;
		latch = 1;
	end
	else begin
		state = nextstate;
	end
end
	




	
always@(posedge CLK) begin
case(state)  

	default:
	begin
		nextstate = LATCH;
	end
	
	  LATCH:
	  begin
				// latch 12 us
				latch = 1;
				if (count == TWELVE_US) begin
						latch = 0;
						count = 0;
						nextstate = WAIT;
				end
				else   count = count + 1;
	  end
	  
	  WAIT:
	  begin
				// wait 6 us, then go to pulse
				if (count == SIX_US) begin
						count = 0;
						pulse = 1;
						currentstate = PULSE;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  PULSE:
	  begin
				// pulse 6 us, then go to returnstate and read data
				if (count == SIX_US) begin
						count = 0;
						pulse = 0;
						if (currentstate == READ_NONE) begin
							if (temp == 3) begin
									temp = 0;
									nextstate = WAIT_TO_LATCH;
							end
							else	currentstate = READ_RIGHT;
						end
						nextstate = currentstate + 1;
				end
				else   count = count + 1;
	  end
	  
	  READ_A:
	  begin
				A = data;
            // wait 6 us, then go to READ_B
				if (count == SIX_US) begin
						A = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_A;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  READ_B:
	  begin
				B = data;
            // wait 6 us, then go to pulse
				if (count == SIX_US) begin
						B = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_B;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  READ_X:
	  begin
				X = data;
            // wait 6 us, then go to pulse
				if (count == SIX_US) begin
						X = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_X;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  READ_Y:
	  begin
				Y = data;
            // wait 6 us, then go to pulse
				if (count == SIX_US) begin
						Y = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_Y;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  READ_L:
	  begin
				L = data;
            // wait 6 us, then go to pulse
				if (count == SIX_US) begin
						L = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_L;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  READ_R:
	  begin
				R = data;
            // wait 6 us, then go to pulse
				if (count == SIX_US) begin
						R = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_R;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end

	  READ_START:
	  begin
				Start = data;
            // wait 6 us, then go to pulse
				if (count == SIX_US) begin
						Start = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_START;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  READ_SELECT:
	  begin
				Select = data;
            // wait 6 us, then go to pulse
				if (count == SIX_US) begin
						Select = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_SELECT;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  READ_UP:
	  begin
				Up = data;
            // wait 6 us, then go to pulse
				if (count == SIX_US) begin
						Up = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_UP;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end

	  READ_DOWN:
	  begin
				Down = data;
				// wait 6 us, then go to pulse
				if (count == SIX_US) begin
					Down = 0;
					count = 0;
					pulse = 1;
					currentstate = READ_DOWN;
					nextstate = PULSE;
				end
				else count = count + 1;
	  end
	  
	  READ_LEFT:
	  begin
				Left = data;
            // wait 6 us, then go to pulse
				if (count == SIX_US) begin
						Left = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_LEFT;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  READ_RIGHT:
	  begin
				Right = data;
            // wait 6 us, then go to pulse
				if (count == SIX_US) begin
						Right = 0;
						count = 0;
						pulse = 1;
						currentstate = READ_RIGHT;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  READ_NONE:
	  begin
            // wait 6 us, then go to READ_NONE x 4
				if (count == SIX_US) begin
						count = 0;
						pulse = 1;
						temp = temp + 1;
						currentstate = READ_NONE;
						nextstate = PULSE;
				end
				else   count = count + 1;
	  end
	  
	  WAIT_TO_LATCH:
	  begin
				// wait 16.67 ms, then go to latch
				if (count == SIXTEEN_MS) begin
						count = 0;
						nextstate = LATCH;
				end
				else   count = count + 1;
	  end
	endcase
	end
endmodule

